/**
 * @file Account.h
 * @author your name (you@domain.com)
 * @brief 
 * @version 0.1
 * @date 2022-11-28
 * 
 * @copyright Copyright (c) 2022
 * 
 */
#pragma once

#include <windows.h>
#include "stdint.h"
#include "../common/Event.hpp"
#include "../common/ConcurrentQueue.hpp"
#include "cxthread.h"

using namespace std;

 /**
  * @brief 账户状态
  *
  */
enum class AccountState
{
	//存钱中
	ACCOUNT_STATE_DEPOSITING,
	//取钱中
	ACCOUNT_STATE_DRAWING,
	//保护态
	ACCOUNT_STATE_PROTECTED,
	//空闲
	ACCOUNT_STATE_IDLE,
};

/**
 * @brief 账户接收的消息类型
 */
enum class AccountServerType
{
	//存
	ACCOUNTSERVER_REQ_PLUS,
	//取
	ACCOUNTSERVER_REQ_SUBTRACT,
	//退出
	ACCOUNTSERVER_REQ_QUIT
};
/**
 * @brief 账户接收的消息
 */
class AccountServerMsg {
public:
	AccountServerType mType;
	uint32_t mVal;
	uint32_t mId;
	AccountServerMsg() { mType = AccountServerType::ACCOUNTSERVER_REQ_QUIT; mVal = 0; };
	AccountServerMsg(uint32_t id, AccountServerType type, uint32_t val) { mId = id; mType = type; mVal = val; };
	virtual ~AccountServerMsg() {}
};



/**
 * @brief 账户发出的事件类型
 * 
 */
enum AcountEventEnum
{
	//余额改变
	MONEY_CHANGE
};

/**
 * @brief 账户发出的事件参数
 */
struct AcountEventArgs {
	AcountEventEnum mType;
	uint32_t mVal;
	uint32_t mId;
};






/**
 * @brief 账户
 * 
 */
class Account {
	protected:
		AccountState m_state; /*!< 账户状态 */
		uint32_t	m_id;      /*!< 账户id */
		uint32_t	m_money;    /*!< 账户余额 */
		uint32_t    m_take_money;  /*!< 记录取钱的金额,对单次取钱金额做限制 */
		/**
		 * @brief 存钱
		 * @param money
		 */
		void deposiMoney(uint32_t money);
		/**
		 * @brief 取钱
		 * @param money
		 */
		void drawMoney(uint32_t money);

		/**
		 * @brief 余额存数据库
		 */
		void save();

		/**
		 * @brief 退出
		 */
		void quit();
		/*
		 * 输出余额改变事件
		 */
		void OutMoneyChangeEvent();
	public:
	
		Account(uint32_t id=0,uint32_t money=0) {
			m_id = id;
			m_money = money;
			m_take_money = 0;
			init();
		}
		virtual ~Account();
		/**
		 * @brief 账户初始化
		 *
		 */
		void init();
		/**
		 * @brief 查询余额
		 * @return uint32_t 
		 */
		uint32_t getMoney() {
			return m_money;
		};
		/**
		 * @brief 消息处理
		 * @param accountServerMsg
		 */
		uint32_t dealAccountServerMsg(AccountServerMsg accountServerMsg);
		
		/**
		 * @brief 查询账户产生的最新消息
		 * @param AcountEventArgs
		 */
		AcountEventArgs  pollAccountEvent();

		uint32_t lastQuitTime;   /*!< 上次退出的的时间 */

};


